// import cell, { lib, register, useState, createStore } from "@aotoo/react-cell";
import cell, { lib, register, useState, createStore } from "./cell";

import "./checkbox";
import "./radiobox";

const accessInputAttributes = [
  "type",
  "inputType",
  "id",
  "className",
  "value",
  "values",
  "options"
];

function Dropdown(props) {
  let dropdownListProps = {};
  let wrapProps = {};
  let tmp = {};
  let ddList = null;
  let $tags = [];
  let emitUnionResponse = null  // 初始化联动响应方法

  const [show, setShow] = useState(() => false);
  const [_props, _setProps] = React.useState(props);
  
  React.useEffect(() => {
    if (show===true) {
      document.dispatchEvent(new Event('click'))
      setShow(true)
    }
  }, [show]);

  // React.useEffect(() => {
  //   set$value(props.value);
  // }, [props.value]);

  // React.useEffect(() => {
  //   set_values(props.values);
  // }, [props.values]);

  const $props = { ..._props };
  const store = $props.store || $props.parent;
  const listStore = createStore();

  
  Object.keys($props).forEach((ky) => {
    if (accessInputAttributes.indexOf(ky) > -1) {
      tmp[ky] = $props[ky];
    } else {
      wrapProps[ky] = $props[ky];
    }
  });



  let $type = tmp.type || tmp.inputType || "dd";
  let $id = tmp.id || "dropdown-list";
  let $className = tmp.className === 'input' ? "dropdown-group" : tmp.className;
  tmp.className = "dropdown-list";



  
  let [$value, _setValue] = React.useState(tmp.value);
  $value = $type === "mdd" ? [].concat($value) : $value;
  function set$value(){
    _setValue.apply(null, arguments)
  }





  /**
   * 处理下拉选项列表
   */
  let [_values, set_values] = React.useState(tmp.options || tmp.values || []);
  let $values = _values.map((val) => {
    if (lib.isString(val)) {
      val = [val, { desc: val }];
    }
    if (lib.isArray(val)) {
      let v = val[0];
      let opts = val[1] || {};
      opts.desc = opts.title
        ? opts.desc
          ? opts.desc
          : null
        : opts.desc || val[0];
      opts.className = opts.className || "dropdown-option";
      if (opts.className.indexOf("dropdown-option") === -1) {
        opts.className = "dropdown-option " + opts.className;
      }

      let oldChange = opts.onChange;
      opts.onChange = function (e, param, inst) {
        let v = e.target.value;
        if ($type === "dd") {
          set$value(v);
          setTimeout(() => {
            setShow(false);
            const unionResponsValue = [v, (val[1].title||val[1].desc) ]
            emitUnionResponse({target: {value: unionResponsValue}});
            if (lib.isFunction(oldChange)) {
              return oldChange(e, param, inst);
            }
          }, 50);
        }

        if ($type === "mdd" && lib.isArray($value)) {
          let $v = inst.getValue();
          let index = $v.indexOf(v);
          if (index > -1) {
            $v.splice(index, 1);
          } else {
            $v.push(v);
          }
          set$value($v);
        }
      };
      val[1] = opts;

      if ($type === "mdd") {
        const unionResponsValue = []
        $value.forEach(($v, ii) => {
          if ($v === v) {
            unionResponsValue.push([v, (opts.title || opts.desc)])
            $tags.push({
              title: opts.title || opts.desc,
              value: v,
              closeIt(e) {
                let index = $value.indexOf(v);
                if (index > -1) {
                  $value.splice(index, 1);
                  set$value($value);
                }
              }
            });
          }
        });
        emitUnionResponse({target: {value: unionResponsValue}});
      }
    }
    return val;
  });

  wrapProps.value = $type === "mdd" ? "" : $value;
  wrapProps.id = $id;

  const header = wrapProps.header;
  const footer = wrapProps.footer;
  delete wrapProps.header;
  delete wrapProps.footer;

  if (wrapProps.id === "dropdown-list") {
    console.warn("需要指定下拉菜单的id，以避免出现未知错误");
  }

  let tagElements = [];
  $tags.forEach((tag, ii) => {
    let { title, value, closeIt } = tag;
    tagElements.push(
      <span className="select-tag" key={`tag-${ii}`} data-value={value}>
        {title}
        <i onClick={closeIt} />
      </span>
    );
  });
  let tagWrap =
    $type === "mdd" && tagElements.length ? (
      <div className="dropdown-prefix">{tagElements}</div>
    ) : null;

  const inputProps = { ...wrapProps };
  const [v, setv] = React.useState(inputProps.value);
  delete inputProps.value;

  const eventResponse = inputProps.onChange;
  const [clientResponsesFun, responsesFun, parentStore, _emitUnionResponse] = eventResponse(
    function (e, param, inst) {
      setv(e.target.value);

      let readOnly = e.target.readOnly;
      let disabled = e.target.disabled;
      if (readOnly || disabled) return;

      if (lib.isString(clientResponsesFun)) {
        if (lib.isFunction(parentStore[clientResponsesFun])) {
          clientResponsesFun = parentStore[clientResponsesFun];
        }
      }

      if (clientResponsesFun.name !== "innerOnChange") {
        const context = {
          setOpthion: function (param) {
            if (lib.isArray(param)) {
              const targetOption = [];
              param.forEach((it) => {
                if (lib.isString(it)) {
                  targetOption.push([it, { title: it, checked: false }]);
                }
                if (lib.isArray(it)) {
                  const itConfig = it[1] || { title: it[0] };
                  itConfig.checked = false;
                  it[1] = itConfig;
                  targetOption.push(it);
                }
              });
              set_values(targetOption);
            }
          }
        };
        if (!show) {
          setShow(true, function () {
            clientResponsesFun.call(context, e);
          });
        } else {
          clientResponsesFun.call(context, e);
        }
      }
    }
  );
  emitUnionResponse = _emitUnionResponse  // 联动方法赋值给上级变量
  inputProps.onChange = responsesFun;

  dropdownListProps.name = $id + "-list";
  dropdownListProps.value = $value;
  dropdownListProps.values = $values;
  dropdownListProps.className = header || footer ? "" : "dropdown-list";

  if ($type === "dd") {
    ddList = <cell.Radiobox data={dropdownListProps} store={parentStore} />;
  } else {
    ddList = <cell.Checkbox data={dropdownListProps} store={parentStore} />;
  }

  function ddListClick(e) {
    e.stopPropagation();
  }

  ddList = (
    <div onClick={ddListClick} className="dropdown-list">
      {header || null}
      {ddList}
      {footer || null}
    </div>
  );

  const ddInst = parentStore.getById($id);
  ddInst.selectAll = function (param) {
    const listInst = parentStore.getById(dropdownListProps.name);
    if (param === undefined || param === null) {
      listInst.selectAll();
    } else {
      if (param === false) {
        listInst.selectAll(false);
      }
      if (param === true) {
        const val = listInst.getValue();
        ddInst.attr("value", val);
      }
    }
  };

  function showMenu(e) {
    e.stopPropagation();
    let toggleShow = !show;
    setShow(toggleShow);
  }

  React.useEffect(() => {
    setv(wrapProps.value);
    setTimeout(() => {
      if (lib.isClient()) {
        document.addEventListener("click", function () {
          setShow(false);
        });
      }
    }, 500);
  }, [wrapProps.value]);

  
  let selectValue = ''  // 选中value的完整值
  if ($type === 'dd') {
    $values.forEach(val=>{
      let value = val
      let opts = {}
      
      if (lib.isArray(val)) {
        value = val[0]
        opts = val[1]
      }
  
      if (value === v) {
        selectValue = opts.title || opts.desc || value
      }
    })
    if (selectValue === '') {
      selectValue = v
    }
  }

  return (
    <div className={$className}>
      <div className="dropdown-head">
        {tagWrap}
        {/* <input type="text" {...inputProps} value={v} onClick={showMenu} className='input' /> */}
        <input type="text" {...inputProps} value={selectValue} onClick={showMenu} className='input' />
      </div>
      {show ? ddList : null}
    </div>
  );
}

register("Dropdown", ["dd", "mdd"], Dropdown);
